﻿using System;
using System.Collections.Generic;
using System.Text;
using SdmxMl.Helper;
using SdmxMl.Structure;

namespace SdmxMl.SmsImportCfg
{
    public class SakeScanQuestion
    {
        private List<string> lines;
        private int limit;
        private int textFinalLine;
        private string lang;


        public string QuestId { get; set; }
        public string Question { get; set; }
        public string InfoInt { get; set; }
        public CodeListType Clt { get; set; }
        public CodeListType CltQuality { get; set; }
        public string Lang { get { return lang; } }


        public SakeScanQuestion(int row, WorkSheetHelper wh, string lg, int blocSize)
        {
            lang = lg;
            limit = 15;
            lines = new List<string>(limit);

            textFinalLine = 0;

            // scanbloc rows from current
            for (int r = 0; r < limit+1; r++)
            {
                if (r == 0)
                {
                    QuestId = wh.GetCellContent(row, 1);
                    //if (wh.GetCellContent(row, 2) != "01")
                    //    throw new ApplicationException("Invalid start of question at line: " + row.ToString());
                    if (QuestId.StartsWith("<") == false)
                        throw new ApplicationException("Invalid start of question at line: " + row.ToString());
                    QuestId = QuestId.TrimStart('<').TrimEnd('>');
                }
                else
                {
                    lines.Add(wh.GetCellContent(row + r, 1));
                }

              //  lines.Add(wh.GetCellContent(row + r, 3));
            }

            GetQuestionText();

            GetInfoIntText();

            GetCodes();

        }


        private void GetQuestionText()
        {
            Question = string.Empty;
         //   int r = 0;
            int r = 0;
            for (; r < limit; r++)
            {
                if (lines[r].Trim().StartsWith("----------") || lines[r].Trim().StartsWith("#e----------") ||
                    lines[r].Trim().StartsWith("<") || IsInterview(lines[r]))
                    break;
            }

       //     if (r < limit)
            {
                if (textFinalLine < r)
                    textFinalLine = r + 1;

                StringBuilder sb = new StringBuilder(128);
                for (int i = 0; i < r; i++)
                    sb.Append(lines[i]).Append(' ');
                Question = sb.ToString().Replace("  ", " ").Trim();      
            }

        }

        private bool IsInterview(string line)
        {
             int ndx = -1;
             return ((ndx = line.IndexOf("INT.:")) >= 0 ||
                 (ndx = line.IndexOf("INT:")) >= 0 ||
                 (ndx = line.IndexOf("Int.:")) >= 0
                 );

        }

        private void GetInfoIntText()
        {
            InfoInt = string.Empty;
            int r = 0;
            int ndx = -1;
            for (; r < limit; r++)
            {
                if (IsInterview(lines[r]))
                    break;
            }

            if (r < limit)
            {

                StringBuilder sb = new StringBuilder(128);
                sb.Append(lines[r++].Substring(ndx + 5)).Append(' '); ;
                while (r < limit && (lines[r].Trim() != string.Empty && lines[r].IndexOf("-") < 0))
                {
                    sb.Append(lines[r++]).Append(' ');
                }

                InfoInt = sb.ToString().Replace("  ", " ").Trim();
            }
        }

        private bool CodeOccurence(int index)
        {
            if (index > limit)
                return false;

            string s = lines[index].Trim();
            return (s.StartsWith("-") &&
                TextTool.CountStringOccurrences(s, "-") == 1 &&
                    TextTool.CountStringOccurrences(s, "<") == 1 &&
                    TextTool.CountStringOccurrences(s, ">") == 1);
        }

        private bool CodeDualOccurence(int index)
        {
            if (index > limit)
                return false;

            string s = lines[index].Trim();
            return (s.StartsWith("-") &&
                TextTool.CountStringOccurrences(s, "-") == 2 &&
                    TextTool.CountStringOccurrences(s, "<") == 2 &&
                    TextTool.CountStringOccurrences(s, ">") == 2);
        }

        private void GetCodes()
        {
            bool onQuality = false;
            CodeListType coList = null;

            int r = textFinalLine;
            while (r < limit)
            {
                if (CodeDualOccurence(r++))
                    return;
            }
            r = textFinalLine;
            while (r < limit)
            {
                if (CodeOccurence(r)) // Start of code detected
                {
                    if (Clt == null )
                    {
                        Clt = new CodeListType();
                        Clt.Id = "CL_" + QuestId;
                        Clt.AgencyId = "CH1_SAKE";
                        Clt.Name.UpdateDefaultText("Codelist for question " + QuestId);
                        coList = Clt;
                    }

                    coList.CodeList.Add(GetOneCode(r));
                }

                // Check for quality mark if codes already detected
                if (Clt != null && onQuality == false)
                {
                    onQuality = lines[r].IndexOf("------------") >= 0;
                    if (onQuality)
                    {
                        CltQuality = new CodeListType();
                        CltQuality.Id = "CL_QUAL_" + QuestId;
                        CltQuality.Name.UpdateDefaultText("Quality codelist for question " + QuestId);
                        coList = CltQuality;
                    }
                }
                ++r;
            }

        }

        private CodeType GetOneCode(int index)
        {
            string[] arr = lines[index].Split('<');
            CodeType c = new CodeType();
            
            int ndx = arr[1].IndexOf('>');
            if (ndx < 0)
                throw new ApplicationException("INvalid ndx for code in " + QuestId);
            c.Id = arr[1].Substring(0, ndx).Trim();
            c.Name.UpdateForLanguage(lang, arr[0].Replace("-", "").Trim().TrimEnd('.').Trim());

            return c;
        }


    }
}
